<template>
  <div id="app">
    <span style="margin-bottom: 5px">{{
      msg ? msg : isPlayChess ? '开始' : '等待'
    }}</span>
    <table style="margin: 0 auto" border="1" cellspacing="0">
      <tr v-for="(tr, y) in chessboard" :key="y">
        <td v-for="(td, x) in tr" :key="x" @click="playChess(td)">
          <div
            :class="{
              chess: true,
              aliceblue: td.piece === 1,
              black: td.piece === 2,
            }"
          >
            {{ td.piece === 0 ? td.attackWeight + td.protectWeight : '' }}
          </div>
        </td>
      </tr>
    </table>
  </div>
</template>

<script>
export default {
  name: 'App',
  data() {
    return {
      // 是否允许下棋
      isPlayChess: true,
      // 棋盘
      chessboard: [],
      msg: '',
      // 攻击权重
      attackWeight: {
        '0020': 20,
        '020': 40,
        '0220': 400,
        '02220': 3000,
        '020220': 3000,
        '022020': 3000,
        '022220': 10000,
        '021': 20,
        '0221': 200,
        '02221': 500,
        '022221': 10000,
      },
      // 防御权重
      protectWeight: {
        '0010': 20,
        '010': 40,
        '0110': 400,
        '01110': 5000,
        '010110': 3000,
        '011010': 3000,
        '011110': 10000,
        '012': 20,
        '0112': 200,
        '01112': 500,
        '011112': 10000,
      },
    };
  },
  // 初始化棋盘
  created() {
    this.chessboard = [];
    for (let y = 0; y < 15; y++) {
      const tr = [];
      for (let x = 0; x < 15; x++) {
        tr.push({
          x: x,
          y: y,
          piece: 0,
          attackWeight: 0,
          protectWeight: 0,
        });
      }
      this.chessboard.push(tr);
    }
  },
  methods: {
    // 白子落子
    playChess(data) {
      if (!this.isPlayChess) {
        return;
      }
      this.isPlayChess = false;
      // console.log(data);
      if (data.piece === 0) {
        data.piece = 1;
      } else {
        this.isPlayChess = true;
        return;
      }
      // 判断是否胜利
      if (this.victory(data, 1)) {
        this.msg = '你赢了';
        setTimeout(() => {
          alert('你赢了!');
        }, 50);
        return;
      }
      // console.log(this.chessboard);
      // 根据权重黑子自动落子
      data = this.setWeightChess();

      if (!data) {
        setTimeout(() => {
          alert('程序落子出错了!');
        }, 50);
        return;
      }

      // 判断黑子是否赢
      if (this.victory(data, 2)) {
        this.msg = '你输了';
        setTimeout(() => {
          alert('你输了!');
        }, 50);
        return;
      }
      this.isPlayChess = true;
    },

    // 判断说输赢
    victory(data, piece) {
      piece = piece === 1 ? '11111' : '22222';
      const around = this.getAround(data, true);
      // console.log(around);
      for (const item of around) {
        if (item.text.indexOf(piece) !== -1) {
          return true;
        }
      }
      return false;
    },
    // 获取周围棋子
    getAround(data, isSetWeight) {
      const around = [];
      for (let index = 0; index < 4; index++) {
        around.push({
          text: '',
          start: '',
          end: '',
        });
      }
      const startY = data.y - 5;
      const startX = data.x - 5;
      const endY = data.y + 5;

      for (let index = 0; index < 11; index++) {
        this.calculateWeight(
          data.y,
          startX + index,
          data,
          around[0],
          isSetWeight
        );
        this.calculateWeight(
          startY + index,
          data.x,
          data,
          around[1],
          isSetWeight,
          true
        );
        this.calculateWeight(
          startY + index,
          startX + index,
          data,
          around[2],
          isSetWeight
        );
        this.calculateWeight(
          endY - index,
          startX + index,
          data,
          around[3],
          isSetWeight
        );
      }
      return around;
    },
    // 计算权重
    calculateWeight(y, x, data, around, isSetWeight, isY) {
      if (y < 0 || y > 14 || x < 0 || x > 14) {
        return;
      }
      const chess = this.chessboard[y][x];

      around.text += chess.piece;

      const a = isY ? y : x;
      const b = isY ? data.y : data.x;
      if (a <= b) {
        around.end += chess.piece;
      }
      if (a >= b) {
        around.start += chess.piece;
      }

      if (chess.piece !== 0 || !isSetWeight) {
        return;
      }

      const aroundz = this.getAround(chess, false);

      for (const item of aroundz) {
        const end = item.end.split('').reverse().join('');
        this.setWeight(item.start, chess);
        this.setWeight(end, chess);
      }

      return chess.piece;
    },
    // 设置权重
    setWeight(text, data, num) {
      for (const key in this.attackWeight) {
        const weight = this.attackWeight[key];
        if (this.mappingWeight(key, text, num)) {
          data.attackWeight += weight;
        }
      }
      for (const key in this.protectWeight) {
        const weight = this.protectWeight[key];
        if (this.mappingWeight(key, text, num)) {
          data.protectWeight += weight;
        }
      }
    },
    // 设置最高权重棋子落子
    setWeightChess() {
      let vacancy = [];
      for (const item of this.chessboard) {
        for (const chess of item) {
          if (
            chess.piece === 0 &&
            chess.protectWeight + chess.attackWeight > 0
          ) {
            vacancy.push(chess);
          }
        }
      }
      vacancy = vacancy.sort((v1, v2) => {
        const num1 = v1.protectWeight + v1.attackWeight;
        const num2 = v2.protectWeight + v2.attackWeight;
        if (num2 > num1) {
          return 1;
        } else if (num1 > num2) {
          return -1;
        } else if (v2.protectWeight > v1.protectWeight) {
          return 1;
        } else if (v2.protectWeight < v1.protectWeight) {
          return -1;
        }
        const random = Math.round(Math.random());
        return random ? 1 : -1;
      });
      // console.log(vacancy);
      if (vacancy.length > 0) {
        vacancy[0].piece = 2;
        return vacancy[0];
      }
    },
    mappingWeight(key, text) {
      const t = text.substring(0, key.length);
      if (key === t || key.split('').reverse().join('') === t) {
        return true;
      }
      return false;
    },
  },
};
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
td {
  width: 30px;
  height: 30px;
  background-color: bisque;
  font-size: 6px;
}
.chess {
  width: 30px;
  height: 30px;
  border-radius: 15px;
}
.black {
  background-color: black;
}
.aliceblue {
  background-color: aliceblue;
}
</style>
